package com.xxxt.hrs.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.xxxt.dao.ClassGradeMapper;
import com.xxxt.dao.CollegeMapper;
import com.xxxt.dao.GradeMapper;
import com.xxxt.dao.SchoolMapper;
import com.xxxt.dao.SpecialtyMapper;
import com.xxxt.dao.StudentMapper;
import com.xxxt.entity.ClassGrade;
import com.xxxt.entity.College;
import com.xxxt.entity.Grade;
import com.xxxt.entity.School;
import com.xxxt.entity.Specialty;
import com.xxxt.entity.Student;
import com.xxxt.utils.CollectionUtil;
import com.xxxt.utils.DateUtil;
import com.xxxt.utils.FileUploadUtil;
import com.xxxt.utils.ImportExcelUtil2;
import com.xxxt.utils.MailUtil;
import com.xxxt.utils.UUIDUtil;

@Transactional
@Service
public class ImportStudentService {
	public static final int ThreadCount = 10; // 线程数量
	@Autowired
	StudentMapper studentMapper;
	@Autowired
	ImportFormAsynController importFormAsynController;
	@Autowired
	private ClassGradeMapper classGradeMapper;
	@Autowired
	private GradeMapper gradeMapper;
	@Autowired
	private SpecialtyMapper specialtyMapper;
	@Autowired
	private CollegeMapper collegeMapper;
	@Autowired
	private SchoolMapper schoolMapper;

	public Map<String, Object> ImportStudentByExcel(MultipartFile fileName, HttpServletRequest request,
			HttpServletResponse response, String tno, String classGradeId) {
		String asName = "temp";// 表格重新命名
		Map<String, Object> map1 = new HashMap<String, Object>();
		try {
			asName = "student_list_" + DateUtil.getCurrentTime("yyyyMMddHHmmss");
		} catch (ParseException e) {
			e.printStackTrace();
			asName = "temp";
		}
		// 文件保存
		File file = FileUploadUtil.upFilebySpring(fileName, request, response, asName, "uploadexcel/temp");
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			// 1:文件不存在
			map1.put("aa", new Integer(1));
			return map1;
		}
		Map<String, String> m = new HashMap<String, String>();// 处理数据为map
		m.put("学校", "school");
		m.put("学院", "college");
		m.put("专业", "specialty");
		m.put("班级", "classGrade");//班级包含年级+班级
		m.put("学号", "sno");
		m.put("姓名", "name");
		List<Map<String, Object>> list_ = null;
		try {
			// 解析excel表格
			list_ = ImportExcelUtil2.parseExcel(fis, file.getName(), m);
			if(list_==null) {
				map1.put("aa", new Integer(2));
				return map1;
			}
			//将excel表格数据总数量返回前台
			map1.put("zonggong", new Integer(list_.size()));
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("表头格式不正确");
			// 2:表头格式不正确
			map1.put("aa", new Integer(4));
			return map1;
		}
		if ("".equals((String) list_.get(0).get("sno")) || list_.get(0).get("sno") == null) {
			System.err.println("学生数据不正确");
			// 3:学生数据不正确
			map1.put("aa", new Integer(3));
			return map1;
		}
		System.out.println("读取到表中的数据" + list_.size() + "条");
		// 对Excel表中重复数据进行处理
		// 创建HashSet集合 去重
		String err = "";
		//首先获得学号集合
		List<String> snosnoList = new ArrayList<String>();
		for (Map<String, Object> map : list_) {
			snosnoList.add((String)map.get("sno"));
		}
		//统计去重之前的数量
		int temp=snosnoList.size();
		List<String> chongfufu = new ArrayList<String>();
		 for  ( int  i  =   0 ; i  <  snosnoList.size()  -   1 ; i ++ )  {       
		      for  ( int  j  =  snosnoList.size()  -   1 ; j  >  i; j -- )  {       
		           if  (snosnoList.get(j).equals(snosnoList.get(i)))  {       
		        	   snosnoList.remove(j);
		        	   chongfufu.add(snosnoList.get(i));
		            }        
		        }        
		      }   
		 for (String string : chongfufu) {
			 for(int i=0;i<snosnoList.size();i++) {
				 if(string.equals(snosnoList.get(i))) {
					 snosnoList.remove(i);
				 }
			 }
		}
		Set<String> snosnoSet = new HashSet<String>();
		//去重
		snosnoSet.addAll(snosnoList);
		snosnoList.clear();
		snosnoList.addAll(snosnoSet);
		//去重完成
		List<Map<String, Object>> newnewnewList = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < snosnoList.size(); i++) {
			for (Map<String, Object> map : list_) {
				String sno = (String) map.get("sno");
				if(sno.equals(snosnoList.get(i))) {
					newnewnewList.add(map);
					}
				}
		}
		//返回表格中重复数据到前台
		map1.put("excelchongfu", new Integer(temp-snosnoSet.size()));
		System.out.println("重复数据" + (temp-snosnoSet.size())+ "条");
		//替换数据
		list_=newnewnewList;
		// 与数据库的表进行比对，定义一个字符串集合
		List<String> chongfuList = new ArrayList<String>();
		List<String> allStudentSno = studentMapper.getAllStudentSno();
		for (int b = 0; b < allStudentSno.size(); b++) {
			for (Map<String, Object> map2 : list_) {
				if (allStudentSno.get(b).equals((String) map2.get("sno"))) {
					chongfuList.add(allStudentSno.get(b));
				}
			}
		}
		//删除重复的账号
		if(chongfuList.size()>0) {
			studentMapper.batchDeleteStudent(chongfuList);
		}
		//返回数据库中重复数据到前台
		map1.put("dbchongfu", new Integer(chongfuList.size()));
		//处理不完整字段数据
		//定义一个新的容器装正确的数据
		List<Map<String, Object>> newnewList = new ArrayList<Map<String, Object>>();
		for (Map<String, Object> map : list_) {
			String sno = (String) map.get("sno");
			String name =(String) map.get("name");
			String school =(String) map.get("school");
			String college =(String) map.get("college");
			String specialty =(String) map.get("specialty");
			String classGrade =(String) map.get("classGrade");
		if(sno!=null&&name!=null&&school!=null&&college!=null&&specialty!=null&&classGrade!=null) {
			newnewList.add(map);
			}
		}
		map1.put("buwanzheng", new Integer(list_.size()-newnewList.size()));
		System.out.println("不完整数据共"+(list_.size()-newnewList.size())+"条");
		//替换数据
		list_=newnewList;
		//定义一个新的容器装正确的数据
				List<Map<String, Object>> newList = new ArrayList<Map<String, Object>>();
				//比较数据，正则判断
				for (Map<String, Object> map : list_) {
					//姓名限定2-4个中文
					String name = (String) map.get("name");
						boolean checkname = MailUtil.checkname(name);
					if(checkname) {
						newList.add(map);
					}
				}
				//返回前台校验不合格数据
				map1.put("buhege", new Integer(list_.size()-newList.size()));
				//将数据进行替换数据
				list_=newList;
		//处理数据的所有空格
		for (Map<String, Object> map : list_) {
			String sno = (String) map.get("sno");
			String name =(String) map.get("name");
			String school =(String) map.get("school");
			String college =(String) map.get("college");
			String specialty =(String) map.get("specialty");
			String classGrade =(String) map.get("classGrade");
			
			String newsno = sno.replace(" ","");
			String newname = name.replace(" ","");
			String newschool = school.replace(" ","");
			String newcollege = college.replace(" ","");
			String newspecialty = specialty.replace(" ","");
			String newclassGrade = classGrade.replace(" ","");
			
			map.put("sno",newsno);
			map.put("name",newname);
			map.put("school",newschool);
			map.put("college",newcollege);
			map.put("specialty",newspecialty);
			map.put("classGrade",newclassGrade);
		}
		//对学校等信息进行处理
		String ji = null;
		String ban = null;
		Map<String,String> snoclass=new HashMap<String, String>();
		Set<Entry<String, String>> entrySet2 = snoclass.entrySet();
		for (Map<String, Object> map : list_) {
			snoclass.put((String)map.get("sno"),(String)map.get("classGrade"));
		}
		ClassGrade classGrade = null;
		Map<String,String> mapp=new HashMap<String, String>();
		for (Map<String, Object> map : newList) {
			School school=null;
			College college=null;
			Specialty specialty=null;
			Grade grade=null;
			//去数据库根据名字查询学校,万一有，则使用，没有则创建
			for (Entry<String, String> entry : entrySet2) {
				String key = entry.getKey();
				String value = entry.getValue();
				if(key.equals((String)map.get("sno"))) {
					if(value.contains("级")) {
						String[] split = value.split("级");
						ji=split[0];
						ji=ji+"级";
						ban=split[1];
					}
					if(!value.contains("级")&&(value.contains("2019")||value.contains("19"))) {
						String[] split = value.split("19");
						ji="2019级";
						ban=split[1];
					}
					if(!value.contains("级")&&(value.contains("2018")||value.contains("18"))) {
						String[] split = value.split("18");
						ji="2018级";
						ban=split[1];
					}
					if(!value.contains("级")&&(value.contains("2017")||value.contains("17"))) {
						String[] split = value.split("17");
						ji="2017级";
						ban=split[1];
					}
					if(!value.contains("级")&&(value.contains("2016")||value.contains("16"))) {
						String[] split = value.split("16");
						ji="2016级";
						ban=split[1];
					}
					if(!value.contains("级")&&(value.contains("2015")||value.contains("15"))) {
						String[] split = value.split("15");
						ji="2015级";
						ban=split[1];
					}
				}
			}
			if(schoolMapper.selcetOneSchoolByName((String) map.get("school")).size()<=0) { 
				//无学校，则创建
				school=new School(UUIDUtil.getUUID(),(String) map.get("school"));
				schoolMapper.insertSchool(school);
			}
			//有学校，则使用
			school= schoolMapper.selcetOneSchoolByName((String) map.get("school")).get(0);
	
			if(collegeMapper.selcetOneCollegeByName((String) map.get("college"), school.getSchoolId())==null) {
				//无学院则创建
				college=new College(UUIDUtil.getUUID(),(String) map.get("college"),school);
				collegeMapper.insertCollege(college);
			}
			//有学院则使用
			college=collegeMapper.selcetOneCollegeByName((String) map.get("college"), school.getSchoolId());
			if(specialtyMapper.selcetOneSpecialtyByName((String) map.get("specialty"), college.getCollegeId())==null) {
				//无专业则创建
				specialty=new Specialty(UUIDUtil.getUUID(),(String) map.get("specialty"),college);
				specialtyMapper.insertSpecialty(specialty);
			}
			//有专业则使用
			specialty=specialtyMapper.selcetOneSpecialtyByName((String) map.get("specialty"), college.getCollegeId());
			
			if(gradeMapper.selectGradeByName(ji, specialty.getSpecialtyId())==null) {
				//无年级则创建
				grade=new Grade(UUIDUtil.getUUID(),ji,specialty);
				gradeMapper.insertGrade(grade);
			}
			//有年级则使用
			grade=gradeMapper.selectGradeByName(ji, specialty.getSpecialtyId());
			
			if(classGradeMapper.selectClassGradeByName(ban, grade.getGradeId())==null){
			//没有班级则创建
				classGrade=new ClassGrade(UUIDUtil.getUUID(),ban,grade);
				classGradeMapper.insertOneClassGrade(classGrade);
				mapp.put((String) map.get("sno"),classGrade.getClassGradeId());
			}
			//有则使用
				classGrade=classGradeMapper.selectClassGradeByName(ban,grade.getGradeId());
				mapp.put((String) map.get("sno"),classGrade.getClassGradeId());
		}
		//拿到学生的key和v
		List<Student> newnewList1 = new ArrayList<Student>();
		Set<Entry<String, String>> entrySet = mapp.entrySet();
		for (Entry<String, String> entry : entrySet) {
			String key = entry.getKey();
			String value = entry.getValue();
			Student student=new Student();
			student.setSno(key);
			student.setClassGrade(new ClassGrade(value));
			newnewList1.add(student);
		}
		// 账号数据
		List<Map<String, Object>> list = new ArrayList<>();
		
		// 处理账号重复数据 避免开启多余线程
		// 学生缓存池
		List<String> sList = studentMapper.getAllStudentSno();
		for (Map<String, Object> map : list_) {
			boolean flag = false;
			for (String s : sList) {
				if (s.equals((String) map.get("sno"))) {
					flag = true;
					err += s + ";";
					break;
				}
			}
			if (!flag) {
				list.add(map);
			}
		}
		
		if (list.size() <= 0) {
			// 3:学生数据不正确
			map1.put("aa", new Integer(3));
			return map1;
		}
		
		// 处理学生数据
		if (list.size() <= 1000) {
			try {
				
				Future<String> results = importFormAsynController.imAccountForm(list, tno,newnewList1);
				results.get();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		} else {
			// 分割数组
			List<List<Map<String, Object>>> lMaps = CollectionUtil.listChunk(list, list.size() / ThreadCount + 10);
			try {
				Collection<Future<String>> results = new ArrayList<>();

				for (List<Map<String, Object>> ls : lMaps) {
					System.err.println("集合大小:" + ls.size());
					results.add(importFormAsynController.imAccountForm(ls, tno,newnewList1));
				}
				// 等待线程执行完毕
				for (Future<String> future : results) {
					future.get();
				}
			} catch (Exception e) {
				e.printStackTrace();
				// 4:内部错误
				map1.put("aa", new Integer(4));
				return map1;
			}
		}
		//0成功
		//返回前台校验成功数据
		map1.put("chenggong",new Integer(list_.size()));
		return map1;
	}

}
